package com.daxia.bumall.web.controller;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.daxia.alipay.service.AlipayService;
import com.daxia.alipay.util.AlipayNotify;
import com.daxia.bumall.common.Logs;
import com.daxia.bumall.common.PayBizType;
import com.daxia.bumall.common.PayStatus;
import com.daxia.bumall.common.PayType;
import com.daxia.bumall.config.PayInit;
import com.daxia.bumall.dto.OrderDTO;
import com.daxia.bumall.dto.PayDTO;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.exception.BizException;
import com.daxia.bumall.model.OrderItem;
import com.daxia.bumall.util.DevUtils;
import com.daxia.wxpay.common.Configure;
import com.daxia.wxpay.common.HttpsRequestNoSSL;
import com.daxia.wxpay.common.Signature;
import com.daxia.wxpay.common.Util;
import com.daxia.wxpay.common.XMLParser;
import com.daxia.wxpay.protocol.pay_protocol.UnifiedOrderReqData;
import com.daxia.wxpay.protocol.refund_query_protocol.WxOrderResData;
import com.daxia.wxpay.service.UnifiedOrderService;

import payment.api.notice.Notice1318Request;
import payment.api.notice.NoticeRequest;
import payment.api.system.PaymentEnvironment;
import payment.api.system.TxMessenger;
import payment.api.tx.marketorder.Tx1312Request;
import payment.api.tx.marketorder.Tx1320Request;
import payment.api.tx.marketorder.Tx1320Response;

@Controller
@RequestMapping("pay")
public class PayController extends BaseController {
	
    private static String successXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
	
	@RequestMapping("tx1312")
	public String tx1312() throws Exception {
		return "pay/pay_tx1312";
	}
	
	private Map<String, String> getParameters(HttpServletRequest request) {
		Map<String, String> returnMap = new HashMap<String, String>();
        Map<String, String> map = request.getParameterMap();
        // String params;
        if (MapUtils.isNotEmpty(map)) {
            for (Object key : map.keySet()) {
                // params.append(key.toString()).append("=").append(map.get(key).toString()).append("\n");
                Object value = map.get(key);
                if (value instanceof String[]) {
                    String[] arr = (String[]) value;
                    returnMap.put(key.toString(), arr[0].toString());
                } else {
                    returnMap.put(key.toString(), value.toString());
                }
            }
        }
        return returnMap;
    }
	
	/**
	 * 选择支付方式
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("choosePayType")
	public String choosePayType(HttpServletRequest request, Map<String, Object> map) throws Exception {
		map.put("parameters", getParameters(request));
		return "pay/pay_choosePayType";
	}
	
	@RequestMapping("setPayType")
	public String setPayType(Integer payBizType,Double amount,Long userId,HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) throws Exception {
		map.put("payBizType", payBizType);
		map.put("amount",amount);
		map.put("userId",userId);
		PayBizType enumPayBizType = PayBizType.getByValue(payBizType);
		String paymentNo = generatePaymentNo(enumPayBizType); //request.getParameter("PaymentNo");
		map.put("paymentNo",paymentNo);
		return "pay/pay_setType";
	}
	
	/**
	 * 查询中金支付结果
	 * @param payemntNo 流水单号
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("queryZJ")
	public String queryZJ(String paymentNo, HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			assertTrue(StringUtils.isNotBlank(paymentNo), "paymentNo不能为空");
			// 1.取得参数
			String institutionID = PayInit.zj_orgNo;

			// 2.创建交易请求对象
			Tx1320Request tx1320Request = new Tx1320Request();
			tx1320Request.setInstitutionID(institutionID);
			tx1320Request.setPaymentNo(paymentNo);

			// 3.执行报文处理
			tx1320Request.process();

			// 4.将参数放置到request对象
			// //2个信息参数
			String message = tx1320Request.getRequestMessage();
			String signature = tx1320Request.getRequestSignature();
			
			//3个交易参数
			String txCode = "1320";
			String txName= "市场订单支付交易查询";
			
			TxMessenger txMessenger = new TxMessenger();
	        String[] respMsg = txMessenger.send(message, signature);
			String plainText = new String(payment.tools.util.Base64.decode(respMsg[0]), "UTF-8");
			logger.debug("[message]=[" + respMsg[0] + "]");
            logger.debug("[signature]=[" + respMsg[1] + "]");
            logger.debug("[plainText]=[" + plainText + "]");
            
            Tx1320Response tx1320Response = new Tx1320Response(respMsg[0], respMsg[1]);
            request.setAttribute("txCode", txCode);
            request.setAttribute("txName", txName);
            request.setAttribute("plainText", tx1320Response.getResponsePlainText());
            if ("2000".equals(tx1320Response.getCode())) {
                logger.info("[Message]=[" + tx1320Response.getMessage() + "]");
                logger.info("[InstitutionID]=[" + tx1320Response.getInstitutionID() + "]");
                logger.info("[PaymentNo]=[" + tx1320Response.getPaymentNo() + "]");
                logger.info("[Amount]=[" + tx1320Response.getAmount() + "]");
                logger.info("[Remark]=[" + tx1320Response.getRemark() + "]");
                logger.info("[Status]=[" + tx1320Response.getStatus() + "]");
                logger.info("[BankNotificationTime]=[" + tx1320Response.getBankNotificationTime() + "]");
                // 处理业务
            }

		} catch (Exception e) {
			e.printStackTrace();
			//processException(request, response, e.getMessage());
		}
	
		return null;
	}
	
	@RequestMapping("gotoPay")
	public String gotoPay(Integer payBizType, Integer payType, Double amount, Long userId, HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) throws Exception {
		try {
			if (DevUtils.isTestServer()) {
				amount = 0.01;
			}
			assertTrue(payBizType != null, "请选择支付类型");
			PayBizType enumPayBizType = PayBizType.getByValue(payBizType);
			
			assertTrue(payType != null, "请选择支付方式");
			PayType enumPayType = PayType.getByValue(payType);
			
			// 公共参数
			// 机构号码
			String institutionID = PayInit.zj_orgNo;
			// 金额，以元为单位
			assertTrue(amount != null && amount > 0, "金额不正确");
			// 用户
			assertTrue(userId != null, "用户不正确");
			UserDTO user = userService.load(userId);
			// 付款者di
			String payerID = userId + ""; // !request.getParameter("PayerID").equals("")?request.getParameter("PayerID").trim():null;
			// 付款者名称
			String payerName = user.getUsername(); // !request.getParameter("PayerName").equals("") ? request.getParameter("PayerName").trim() : null;
			
			// 支付流水号
			String paymentNo = generatePaymentNo(enumPayBizType); //request.getParameter("PaymentNo");
			
			// 创建支付记录
			PayDTO p = new PayDTO();
            p.setPayType(payType);
            p.setStatus(PayStatus.NotPay.getValue());
            p.setAmount(new BigDecimal(amount*100).intValue());
            p.setBizType(payBizType);
            p.setPaymentNo(paymentNo);
            p.setUser(user);
            p.setIsSuccess(false);
            p.setCreateTime(new Date());
            
			
			// 跟具体支付类型相关的数据
            // 订单号
            String orderNo = "";
            // 资金用途
            String usage = "";
            // 订单描述
            String remark = "";
            // 用户自定义信息
            String note = "";
            //微信或者支付宝需要显示的商品名称
            String showDetail = "";
            // 通知url
            String notificationURL = PayInit.zj_notifyUrl;
            if (enumPayBizType == PayBizType.Buy) {
            	String orderIds = ServletRequestUtils.getStringParameter(request, "orderIds");
            	if (StringUtils.isNotBlank(orderIds)) {
            		OrderDTO order = orderService.load(Long.parseLong(orderIds.split(",")[0]));
            		orderNo = order.getOrderNo();
            		List<OrderItem> items = order.getOrderItems();
            		OrderItem firstItem = items.get(0);
            		StringBuffer detailBuffer = new StringBuffer();
            		detailBuffer.append(firstItem.getProduct().getName());
            		detailBuffer.append("  ").append(firstItem.getSpecification().getSpec1());
            		detailBuffer.append("  ").append(firstItem.getSpecification().getSpec2());
            		detailBuffer.append("等商品");
            		showDetail = detailBuffer.toString();
            		usage = "商品购买";
            		remark = "商品购买";
            		note = "";
            		p.setOrderIds(orderIds);
            	} else {
            		Long orderId = ServletRequestUtils.getLongParameter(request, "orderId");
            		OrderDTO order = orderService.load(orderId);
            		orderNo = order.getOrderNo();
            		List<OrderItem> items = order.getOrderItems();
            		OrderItem firstItem = items.get(0);
            		StringBuffer detailBuffer = new StringBuffer();
            		detailBuffer.append(firstItem.getProduct().getName());
            		detailBuffer.append("  ").append(firstItem.getSpecification().getSpec1());
            		detailBuffer.append("  ").append(firstItem.getSpecification().getSpec2());
            		detailBuffer.append("等").append(order.getOrderItems().size()).append("件商品");
            		showDetail = detailBuffer.toString();
            		usage = "商品购买";
            		remark = "商品购买";
            		note = "";
            		p.setOrder(order);
				}
            } else if (enumPayBizType == PayBizType.FactoryRegister) {
            	usage = "新增工厂";
            	remark = "新增工厂";
            	showDetail = "新增工厂";
            	note = "";
            	orderNo = generatePaymentNo(enumPayBizType);
            } else if (enumPayBizType == PayBizType.CompanyRegister) {
            	usage = "新增设计公司";
            	remark = "新增设计公司";
            	showDetail = "新增设计公司";
            	note = "";
            	orderNo = generatePaymentNo(enumPayBizType);
            } else if (enumPayBizType == PayBizType.SubAccountRegister) {
            	usage = "新增设计公司";
            	remark = "新增设计公司";
            	showDetail = "新增设计公司";
            	note = "";
            	orderNo = generatePaymentNo(enumPayBizType);
            	//notificationURL = request.getSession().getAttribute("ctx") + "/admin/user/newSubAccount?startIndex=2";
			}
           
            // 收款人
            String payees = request.getParameter("Payees");

            // 2.创建交易请求对象

            // 5.转向Request.jsp页面
            //request.getRequestDispatcher("/Request.jsp").forward(request, response);
            
            
            // 创建pay对象
            payService.create(p);
            if(payType == PayType.WX.getValue()) {   //如果是微信支付，需要返回到微信内容中，微信内容需要将得到的链接组成一个url
            	if (StringUtils.isNotBlank(p.getOrderIds())) {
            		map.put("order",orderService.load(Long.parseLong(p.getOrderIds().split(",")[0])));
            	} else {
            		map.put("order", p.getOrder());
            	}
            	map.put("amount",amount);
            	String body = "达达订货 正式付款";
                String attach = "购买和注册付款";
                String outTradeNo = p.getPaymentNo();
                int totalFee = new BigDecimal(amount*100).intValue();
                //int totalFee = 1;
                String spBillCreateIP = "120.55.190.175";
                map.put("payBizType", payBizType);
                        
                String appid = "wx3bb22e6f66087555";
                String merchantId = "1267043101";
                String key = Configure.key;
                String wxNotificationURL = "http://120.55.190.175:8080/pay/notificationWX";
                UnifiedOrderReqData reqData = new UnifiedOrderReqData(appid, merchantId, key, body, attach, outTradeNo, totalFee, spBillCreateIP, wxNotificationURL);
                UnifiedOrderService service = new UnifiedOrderService();
                service.setServiceRequest(new HttpsRequestNoSSL());
                String xml = service.sendPost(reqData);
                WxOrderResData resData = XMLParser.wxpayQuery(xml);    //解析返回xml
                Logs.COMMON.debug("xml = "+xml);
                map.put("payUrl",resData.getCodeUrl());
                map.put("wxData",resData);
                map.put("paymentNo", paymentNo);
                map.put("payDetal",showDetail);
            	return "pay/pay_weixin";
            } else if(payType == PayType.Alipay.getValue()) {   //支付宝支付
            	String subject = "达达订货账单支付";    
            	String body = "达达订货账单支付";
            	String totalFee = amount+"";   //1分钱
            	//String totalFee = "0.1";
            	AlipayService alipayService = new AlipayService();
            	String formStr = alipayService.generateSubmitForm(p.getPaymentNo(), subject, totalFee, body);
            	map.put("formInfo",formStr);
            	Logs.COMMON.debug("formInfo = "+formStr);
            	return "pay/pay_alipay";
            } else {   //中金支付
            	 Long payAmount = new BigDecimal(amount*100).longValue();
                 Tx1312Request tx1312Request = new Tx1312Request();
                 tx1312Request.setInstitutionID(institutionID);
                 tx1312Request.setOrderNo(orderNo);
                 tx1312Request.setPaymentNo(paymentNo);
                 tx1312Request.setAmount(payAmount);
                 tx1312Request.setPayerID(payerID);
                 tx1312Request.setPayerName(payerName);
                 tx1312Request.setUsage(usage);
                 tx1312Request.setRemark(remark);
                 tx1312Request.setNote(note);
                 tx1312Request.setNotificationURL(notificationURL);
                 if (null != payees && payees.length() > 0) {
                     String[] payeeList = payees.split(";");
                     for (int i = 0; i < payeeList.length; i++) {
                         tx1312Request.addPayee(payeeList[i]);
                     }
                 }

                 // 3.执行报文处理
                 tx1312Request.process();

                 // 4.将参数放置到request对象
                 // //3个交易参数
                 map.put("plainText", tx1312Request.getRequestPlainText());
                 map.put("message", tx1312Request.getRequestMessage());
                 map.put("signature", tx1312Request.getRequestSignature());
                 // //2个信息参数
                 map.put("txCode", "1312");
                 map.put("txName", "市场订单支付（不要确认）");
                 // 1个action(支付平台地址)参数
                 map.put("action", PaymentEnvironment.paymentURL);
            	return "pay/pay_request";
            }
        } catch (Exception e) {
            e.printStackTrace();
            //processException(request, response, e.getMessage());
        }
		return "";
	}
	
	private String generatePaymentNo(PayBizType enumPayBizType) {
		String no = "";
		if (enumPayBizType == PayBizType.Buy) {
			no += "BY";
		} else if (enumPayBizType == PayBizType.FactoryRegister) {
			no += "FR";
		} else if (enumPayBizType == PayBizType.CompanyRegister) {
			no += "CR";
		}
		no += enumPayBizType.getValue();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		
		no += dateFormat.format(new Date());

		no += (1000 + new Random().nextInt(8999));
		
		return no;
	}

	private String generatePaymentNo() {
		// TODO Auto-generated method stub
		return null;
	}
	
	/**
	 * 此处查询，需要分两次查询，第一次，直接进我方pay表，查到该支付记录状态，如果成功，直接返回，如果没有支付，再去微信服务端查询订单状态
	 * @param resData   微信生成链接时的传入对象
	 * @param payId     支付id
	 * @param map       
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("checkWxPayStatus")
	public String checkWxPayStatus(WxOrderResData resData,String paymentNo,Map<String, Object> map,HttpServletRequest request) throws Exception {
		PayDTO payInfo = new PayDTO();
		payInfo = payService.findByPaymentNo(paymentNo);
		if(payInfo.getStatus() != PayStatus.Payed.getValue()) {    //已经支付成功，直接返回
			// 查询订单
	        Map<String, Object> queryMap = new HashMap<String, Object>();
	        queryMap.put("appid", resData.getAppid());
	        queryMap.put("mch_id", resData.getMchid());
	        queryMap.put("out_trade_no", paymentNo);
	        queryMap.put("nonce_str", resData.getNoncestr());
	        String sign = Signature.getSign(queryMap,Configure.key);
	        queryMap.put("sign", sign);
	        
	        String xml = "<xml>";
	        
	        xml += "<appid>" + queryMap.get("appid").toString() + "</appid>";
	        xml += "<mch_id>" + queryMap.get("mch_id").toString() + "</mch_id>";
	        xml += "<out_trade_no>" + queryMap.get("out_trade_no").toString() + "</out_trade_no>";
	        xml += "<nonce_str>" + queryMap.get("nonce_str").toString() + "</nonce_str>";
	        xml += "<sign>" + queryMap.get("sign").toString() + "</sign>";
	        
	        xml += "</xml>";
	        
	        String resultXml = null;
	        int failedCount = 0;
	        while (true) {
	            HttpsRequestNoSSL httpsRequestNoSSL = new HttpsRequestNoSSL();
	            resultXml = httpsRequestNoSSL.sendPost("https://api.mch.weixin.qq.com/pay/orderquery", xml);
	            if (StringUtils.isBlank(resultXml)) {
	                if (failedCount++ == 2) {
	                    throw new RuntimeException("系统异常，请稍后重试");
	                }
	            } else {
	                break;
	            }
	        }
	        
	        Map<String, Object> resultMap = XMLParser.getMapFromXML(resultXml);
	        logger.error("wxpayquery, orderno: " + paymentNo + ", resultXml: " + resultXml);
	        
	       /* String returnSign = resultMap.get("sign").toString();
	        resultMap.remove("sign");
	        String mySign = Signature.getSign(resultMap,Configure.key);
	        
	        if (!returnSign.equals(mySign)) {
	            throw new BizException("订单查询签名不正确!");
	        }*/
	        
	        String returnCode = resultMap.get("return_code").toString();
	        if (!"success".equalsIgnoreCase(returnCode)) {
	            throw new BizException(resultMap.get("return_msg").toString());
	        }
	        
	        String resultCode = resultMap.get("result_code").toString();
	        if (!"success".equalsIgnoreCase(resultCode)) {
	            throw new BizException(resultMap.get("err_code").toString() + ": " + resultMap.get("err_code_des").toString());
	        }
	        
	        /*
	         *  SUCCESS—支付成功
	            REFUND—转入退款
	            NOTPAY—未支付
	            CLOSED—已关闭
	            REVOKED—已撤销
	            USERPAYING--用户支付中
	            PAYERROR--支付失败(其他原因，如银行返回失败) 
	         */
	        
	        String state = resultMap.get("trade_state").toString();
	        String stateDescription = null; // resultMap.get("trade_state_desc").toString();
	        
	        JSONObject json = new JSONObject();
	        if ("SUCCESS".equalsIgnoreCase(state)) {
	            stateDescription = "支付成功";
	            // 只更新余额，不购买
	            payService.updatePayStatus(payInfo.getId(), PayStatus.Payed.getValue());
	            payService.onSuccess(payInfo.getPaymentNo());
	            // 更新完后马上购买
	            return okJson();
	        } else {
	            json.put("success", false);
	            json.put("msg", "支付未成功,请继续支付");
	            return json.toJSONString();
	        }

		}
		return okJson();
	}
	
	@ResponseBody
	@RequestMapping("alipayNotify")
	public String alipayNotify(HttpServletRequest request) throws Exception {   //支付宝支付后异步通知
		//获取支付宝GET过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap(); 
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			valueStr = new String(valueStr);
			params.put(name, valueStr);
		}
		Logs.COMMON.debug("支付宝支付后异步通知requestParams="+params);
		Logs.COMMON.debug("支付宝支付后异步通知paramsInfo = "+params);
		
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		//计算得出通知验证结果
		boolean verify_result = AlipayNotify.verify(params);
		if(verify_result){//验证成功
			Logs.COMMON.debug("支付宝支付后异步通知支付宝验证成功，状态="+trade_status);
			//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
				//判断该笔订单是否在商户网站中已经做过处理
				//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				//如果有做过处理，不执行商户的业务程序
				PayDTO p = payService.findByPaymentNo(out_trade_no);   //查到订单内容
				if (p.getStatus() == PayStatus.Payed.getValue()) {
					// 已经支付了就不作处理
				} else {
					payService.wxPaySuccess(out_trade_no);   //
				}
			} else {
				Logs.COMMON.debug("支付宝支付后异步通知支付失败...,状态="+trade_status);
				payService.onFailed(out_trade_no, "支付失败!");
			}
		}else{
			//该页面可做页面美工编辑
			Logs.COMMON.debug("支付宝支付后异步通知支付失败...,状态="+trade_status);
		}
		return "SUCCESS";
	}
	
	@RequestMapping("alipayReturn")
	public String alipayReturn(HttpServletRequest request) throws Exception {  //支付宝支付后返回页面
		//获取支付宝GET过来反馈信息
		Map<String,String> params = new HashMap<String,String>();      
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next(); 
			String[] values = (String[]) requestParams.get(name);
			String valueStr = ""; 
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			valueStr = new String(valueStr); 
			params.put(name, valueStr);
		}
		Logs.COMMON.debug("支付宝支付后返回requestParams="+params);		
		Logs.COMMON.debug("支付宝支付后返回 paramsInfo = "+params);  
		  
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		//计算得出通知验证结果
		boolean verify_result = AlipayNotify.verify(params);
		if(verify_result){//验证成功
			Logs.COMMON.debug("支付宝支付后返回支付宝验证成功，状态="+trade_status);
			//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
				//判断该笔订单是否在商户网站中已经做过处理
				//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				//如果有做过处理，不执行商户的业务程序
				PayDTO p = payService.findByPaymentNo(out_trade_no);   //查到订单内容
				payService.wxPaySuccess(out_trade_no);   //
				// 根据不同的业务类型返回到不同的页面进行支付结果展示
				return gotoSuccessPage(p.getBizType());
			} else {
				payService.onFailed(out_trade_no, "支付宝支付后返回支付失败!");
			}
		}else{
			//该页面可做页面美工编辑
			Logs.COMMON.debug("支付失败...,状态="+trade_status);
		}
		return "";
	}

	/**
	 * 微信的异步通知
	 * @return
	 */
	@Transactional
	@ResponseBody
	@RequestMapping("notificationWX")
	public String notificationWX(HttpServletRequest request) throws Exception {
		InputStream is = request.getInputStream(); 
        String xml = Util.inputStreamToString(is);
        if (logger.isDebugEnabled()) {
            logger.debug("notify, xml: " + xml);
        }
        Map<String, Object> map = XMLParser.getMapFromXML(xml);
        String sign = map.get("sign").toString();
        map.remove("sign");
        String mySign = Signature.getSign(map,Configure.key);
        
        /*if (!sign.equals(mySign)) {
            throw new BizException("异步通知签名不正确!");
        }*/
        
        String orderNo = map.get("out_trade_no").toString();
        
        String returnCode = map.get("return_code").toString();
        Logs.COMMON.debug("orderNo = "+orderNo+" and returnCode = " +returnCode);
        if (!"success".equalsIgnoreCase(returnCode)) {
            Long payId = null;
			String msg = null;
			payService.onFailed(orderNo, msg);
            throw new BizException(map.get("return_msg").toString()); 
        }
        
        String resultCode = map.get("result_code").toString();
        if (!"success".equalsIgnoreCase(resultCode)) {
			String msg = null;
			payService.onFailed(orderNo, msg);
            throw new BizException(map.get("err_code").toString() + ": " + map.get("err_code_des").toString());
        }
        payService.wxPaySuccess(orderNo);
        
        //onlinePayService.updatePayResult(orderNo, OnlinePayBankStatus.Succeed.getValue() + "");
        
        return successXml;
    
	}
	
	@RequestMapping("gotoSuccess")
	public String gotoSuccessPage(Integer payBizType) {
		// 根据不同的业务类型返回到不同的页面进行支付结果展示
        if (payBizType == PayBizType.Buy.getValue()) {
        	return "order/paySuccess"; // 返回到购物的订单成功显示页面
        } else if (payBizType == PayBizType.FactoryRegister.getValue()) {
        	return "user/user_companyRegisterStepTh";
        } else if(payBizType == PayBizType.CompanyRegister.getValue()) {
        	return "user/mini/user_companyMiniStepTh";
        } else if (payBizType == PayBizType.SubAccountRegister.getValue()) {
			return "redirect:/admin/user/newSubAccount?startIndex=2";
		}
        return "";
	}
	
	@Transactional
	@RequestMapping("notificationZJ")
	public String notificationZJ(HttpServletRequest request) throws Exception {
		logger.info("---------- Begin [ReceiveNoticePage] process......");
        // 获得参数message和signature
        String message = request.getParameter("message");
        String signature = request.getParameter("signature");

        logger.info("[message]=[" + message + "]");
        logger.info("[signature]=[" + signature + "]");
        // 定义变量
        String txName = "";

        // 生成交易结果对象
        NoticeRequest noticeRequest = new NoticeRequest(message, signature);
        logger.info("noticeRequest: " + ToStringBuilder.reflectionToString(noticeRequest));
        
        Notice1318Request nr = new Notice1318Request(noticeRequest.getDocument());
        // ！！！ 在这里添加商户处理逻辑！！！
        // 以下为演示代码
        txName = "市场订单支付状态变更通知";
        logger.info("[TxCode]       = [1318]");
        logger.info("[TxName]       = [市场订单支付状态变更通知]");
        logger.info("[InstitutionID]= [" + nr.getInstitutionID() + "]");
        logger.info("[PaymentNo]    = [" + nr.getPaymentNo() + "]");
        logger.info("[Amount]       = [" + nr.getAmount() + "]");
        logger.info("[Status]       = [" + nr.getStatus() + "]");
        logger.info("[BankNotificationTime]       = [" + nr.getBankNotificationTime() + "]");
        
        PayDTO p = payService.findByPaymentNo(nr.getPaymentNo());
        if (p == null) {
        	logger.error("找不到支付记录, 流水号：" + nr.getPaymentNo());
        	return "";
        }
        p.setStatus(PayStatus.Payed.getValue());
        p.setResponseStatus(nr.getStatus() + "");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        p.setResponseTime(dateFormat.parse(nr.getBankNotificationTime()));
        // p.setResponseMsg(nr.get);
        if (20 == nr.getStatus()) { // 20就是交易成功
            logger.info("receive 1318 notification success");
            p.setIsSuccess(true);
        } else {
        	p.setIsSuccess(false);
        }
        payService.updateAllFields(p);
        if (p.getIsSuccess()) {
        	payService.onSuccess(p);
        }
        // 根据不同的业务类型返回到不同的页面进行支付结果展示
        /*if (p.getBizType() == PayBizType.Buy.getValue()) {
        	return "order/paySuccess"; // 返回到购物的订单成功显示页面
        } else if (p.getBizType() == PayBizType.FactoryRegister.getValue()) {
        	return "user/user_companyRegisterStepTh";
        } else if(p.getBizType() == PayBizType.CompanyRegister.getValue()) {
        	return "user/mini/user_companyMiniStepTh";
        }*/
		return gotoSuccessPage(p.getBizType());
	}
}	